package utilities;

import galaxies.enums.EarthLike;
import galaxies.enums.GalaxyDensity;
import galaxies.enums.GalaxySize;
import galaxies.enums.ResearchRate;
import galaxies.enums.SpiralArmNumbers;
import gameAppLayer.ExternalData;
import gameAppLayer.enums.Constants;
import gameAppLayer.enums.TextureList;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import audio.enums.AudioInformation;
import audio.enums.AudioParameters;

import stars.enums.StarParameters;
import stars.enums.StarSystemDistributions;
import stars.enums.StarSystemNames;
import stars.enums.StarSystemParameters;
import stars.enums.StarTypeData;

public class ExternalDataLoader {
	
	private static final Logger logger = Logger.getLogger(ExternalDataLoader.class.getName());
	
	private ExternalData data = new ExternalData();
	
	public ExternalData execute() throws IOException, ClassNotFoundException {
		
		logger.log(Level.INFO, "execute()");
		
//		ArrayList<File> files = new ArrayList<File>();
		
		//-----------------------------------------
		//Create file objects
		
//		files.add(new File(Constants.dataPath + "//StarData.txt"));
//		files.add(new File(Constants.dataPath + "//StarSystemData.txt"));
//		files.add(new File(Constants.dataPath + "//SpiralArmNumbers.txt"));
//		files.add(new File(Constants.dataPath + "//ResearchRate.txt"));
//		files.add(new File(Constants.dataPath + "//GalaxyDensity.txt"));
//		files.add(new File(Constants.dataPath + "//EarthLike.txt"));
//		files.add(new File(Constants.dataPath + "//GalaxySize.txt"));
//		files.add(new File(Constants.dataPath + "//SystemNames.txt"));
//		files.add(new File(Constants.dataPath + "//CustomGalaxies"));
		
		//Continue...
		
//		logger.log(Level.INFO, "files created");
		//-----------------------------------------
		
		
		
		
		logger.log(Level.INFO, "loading files");
		
		File file;
		FileReader fr;
		BufferedReader br;
		String result = "NA";
		
		
		//-----------------------------------------		
		//StarData.txt
		file = new File(Constants.dataPath + "//StarData.txt");
		fr = new FileReader(file);		
		br = new BufferedReader(fr);
		
		//ArrayList<StarTypeData> starDataList = new ArrayList<StarTypeData>();
		
		result = br.readLine();
		result = br.readLine();
		
		StarParameters params = new StarParameters();
		
		logger.log(Level.INFO, "Reading StarData.txt");
		
		while (result!=null) {			
			String[] pieces = result.split("\t");
			
			StarTypeData starData = new StarTypeData(pieces[0]);				
			starData.setYoungProb(Double.parseDouble(pieces[1]));
			starData.setAverageProb(Double.parseDouble(pieces[2]));
			starData.setOldProb(Double.parseDouble(pieces[3]));
			starData.setMaxLuminance(Double.parseDouble(pieces[4]));
			starData.setMinLuminance(Double.parseDouble(pieces[5]));
			starData.setMaxTemp(Double.parseDouble(pieces[6]));
			starData.setMinTemp(Double.parseDouble(pieces[7]));
			starData.setMaxMass(Double.parseDouble(pieces[8]));
			starData.setMinMass(Double.parseDouble(pieces[9]));
			starData.setMaxRadius(Double.parseDouble(pieces[10]));
			starData.setMinRadius(Double.parseDouble(pieces[11]));
			starData.setMaxRotation(Double.parseDouble(pieces[12]));
			starData.setMinRotation(Double.parseDouble(pieces[13]));
			starData.setMaxMagField(Double.parseDouble(pieces[14]));
			starData.setMinMagField(Double.parseDouble(pieces[15]));
			starData.setBinaryProb(Double.parseDouble(pieces[16]));
			starData.setTrinaryProb(Double.parseDouble(pieces[17]));
			starData.setQuadProb(Double.parseDouble(pieces[18]));
			starData.setColor(pieces[19]);
			
			ArrayList<Float> RGBColorVals = new ArrayList<Float>();
			RGBColorVals.add(Float.parseFloat(pieces[20]));
			RGBColorVals.add(Float.parseFloat(pieces[21]));
			RGBColorVals.add(Float.parseFloat(pieces[22]));
			starData.setRGBColorVals(RGBColorVals);
			
			ArrayList<Float> RGBGlowColorVals = new ArrayList<Float>();
			RGBGlowColorVals.add(Float.parseFloat(pieces[23]));
			RGBGlowColorVals.add(Float.parseFloat(pieces[24]));
			RGBGlowColorVals.add(Float.parseFloat(pieces[25]));
			starData.setRGBGlowColorVals(RGBGlowColorVals);
			
			starData.setDisplaySize(Float.parseFloat(pieces[26]));
			starData.addTexture("Quiet", Constants.texturesPath + pieces[27]);
			starData.addTexture("Average", Constants.texturesPath + pieces[28]);
			starData.addTexture("Active", Constants.texturesPath + pieces[29]);
			starData.addTexture("Blank", Constants.texturesPath + pieces[30]);
			starData.addTexture("Far", Constants.texturesPath + pieces[31]);
//			starData.addTexture("HighSpin", Constants.texturesPath + pieces[32]);
//			starData.addTexture("FarHighSpin", Constants.texturesPath + pieces[33]);
//			starData.addTexture("Starquakes", Constants.texturesPath + pieces[34]);
//			starData.addTexture("Flares", Constants.texturesPath + pieces[35]);
			
			
			params.addParameter(pieces[0], starData);
			
			result = br.readLine();
		}		
		br.close();
		
		data.setStarParameters(params);
		//-----------------------------------------
		
		
		//-----------------------------------------
		//StarSystemDistributions
		file = new File(Constants.dataPath + "//StarSystemDistributions.txt");
		fr = new FileReader(file);		
		br = new BufferedReader(fr);
		
		result = br.readLine();
		result = br.readLine();
		
		StarSystemDistributions sysDist = new StarSystemDistributions();
		HashMap<String, Double> sysDistData = new HashMap<String, Double>();
		
		logger.log(Level.INFO, "Reading StarSystemDistributions.txt");
		
		while (result!=null) {
			String[] pieces = result.split("\t");
			sysDistData.put(pieces[0], Double.parseDouble(pieces[1]));
			result = br.readLine();
		}
		br.close();
		sysDist.setProbabilities(sysDistData);
		data.setStarSystemDistributions(sysDist);
		//-----------------------------------------
		
		
		//-----------------------------------------
		//StarSystemParameters
		file = new File(Constants.dataPath + "//StarSystemData.txt");
		fr = new FileReader(file);		
		br = new BufferedReader(fr);
		
		result = br.readLine();
		result = br.readLine();
		
		StarSystemParameters sysParams = new StarSystemParameters();		
		HashMap<String, Double> sysParamsMap = new HashMap<String, Double>();
		
		logger.log(Level.INFO, "Reading StarSystemParameters.txt");
		
		while (result!=null) {
			String[] pieces = result.split("\t");
			sysParamsMap.put(pieces[0], Double.parseDouble(pieces[1]));
			result = br.readLine();
		}
		br.close();
		sysParams.setParameters(sysParamsMap);
		data.setStarSystemParameters(sysParams);
		//-----------------------------------------
		
		
		//-----------------------------------------
		//StarSystemNames
		file = new File(Constants.dataPath + "//SystemNames.txt");
		fr = new FileReader(file);
		br = new BufferedReader(fr);

		result = br.readLine();
		ArrayList<String> entries = new ArrayList<String>();
		StarSystemNames sysNames = new StarSystemNames();

		logger.log(Level.INFO, "Reading StarSystemNames.txt");
		
		while (result != null) {
			entries.add(result);
			result = br.readLine();
		}
		br.close();

		sysNames.setEntries(entries);
		data.setStarSystemNames(sysNames);
		//-----------------------------------------


		//-----------------------------------------
		//SpiralArmNumbers
		file = new File(Constants.dataPath + "//SpiralArmNumbers.txt");
		fr = new FileReader(file);
		br = new BufferedReader(fr);

		result = br.readLine();
		result = br.readLine();
		HashMap<String, Integer> armNumbers = new HashMap<String, Integer>();
		SpiralArmNumbers spiralArmNumbers = new SpiralArmNumbers();

		logger.log(Level.INFO, "Reading SpiralArmNumbers.txt");
		
		while (result != null) {
			String[] pieces = result.split("\t");
			armNumbers.put(pieces[0], Integer.parseInt(pieces[1]));
			result = br.readLine();
		}
		br.close();

		spiralArmNumbers.setSpiralArmNumbers(armNumbers);
		data.setArmNumbers(spiralArmNumbers);
		//-----------------------------------------


		//-----------------------------------------
		//ResearchRate
		file = new File(Constants.dataPath + "//ResearchRate.txt");
		fr = new FileReader(file);
		br = new BufferedReader(fr);

		result = br.readLine();
		result = br.readLine();
		HashMap<String, Double> rates = new HashMap<String, Double>();
		ResearchRate researchRate = new ResearchRate();

		logger.log(Level.INFO, "Reading ResearchRate.txt");
		
		while (result != null) {
			String[] pieces = result.split("\t");
			rates.put(pieces[0], Double.parseDouble(pieces[1]));
			result = br.readLine();
		}
		br.close();

		researchRate.setResearchRate(rates);
		data.setResearchRate(researchRate);
		//-----------------------------------------


		//-----------------------------------------
		//GalaxySize
		file = new File(Constants.dataPath + "//GalaxySize.txt");
		fr = new FileReader(file);
		br = new BufferedReader(fr);

		result = br.readLine();
		result = br.readLine();
		HashMap<String, Integer> sizes = new HashMap<String, Integer>();
		GalaxySize galSize = new GalaxySize();
		
		logger.log(Level.INFO, "Reading GalaxySize.txt");
		
		//QQQ:  Fix below code to concatenate column headings with rows.
		while (result != null) {
			String[] pieces = result.split("\t");
			sizes.put(pieces[0], Integer.parseInt(pieces[1]));
			sizes.put(pieces[0], Integer.parseInt(pieces[2]));
			sizes.put(pieces[0], Integer.parseInt(pieces[3]));			
			
			result = br.readLine();
		}
		br.close();

		galSize.setGalaxySizes(sizes);
		data.setGalSize(galSize);
		//-----------------------------------------
		
		
		//-----------------------------------------
		//GalaxyDensity
		file = new File(Constants.dataPath + "//GalaxyDensity.txt");
		fr = new FileReader(file);
		br = new BufferedReader(fr);

		result = br.readLine();
		result = br.readLine();
		HashMap<String, Integer> densities = new HashMap<String, Integer>();
		GalaxyDensity galDensities = new GalaxyDensity();
		
		logger.log(Level.INFO, "Reading GalaxyDensity.txt");
		
		//QQQ:  Fix below code to concatenate column headings with rows.
		while (result != null) {
			String[] pieces = result.split("\t");
			densities.put(pieces[0], Integer.parseInt(pieces[1]));						
			
			result = br.readLine();
		}
		br.close();

		galDensities.setDensity(densities);
		data.setGalDensity(galDensities);
		//-----------------------------------------
		
		
		//-----------------------------------------
		//Earthlike
		file = new File(Constants.dataPath + "//GalaxyDensity.txt");
		fr = new FileReader(file);
		br = new BufferedReader(fr);

		result = br.readLine();
		result = br.readLine();
		HashMap<String, Double> probs = new HashMap<String, Double>();
		EarthLike earthLike = new EarthLike();
		
		logger.log(Level.INFO, "Reading Earthlike.txt");
		
		//QQQ:  Fix below code to concatenate column headings with rows.
		while (result != null) {
			String[] pieces = result.split("\t");
			probs.put(pieces[0], Double.parseDouble(pieces[1]));						
			
			result = br.readLine();
		}
		br.close();

		earthLike.setEarthLikeProbs(probs);
		data.setEarthLike(earthLike);
		//-----------------------------------------
		
		
		//-----------------------------------------
		//TextureList
		file = new File(Constants.dataPath + "//TextureList.txt");
		fr = new FileReader(file);
		br = new BufferedReader(fr);
		
		result = br.readLine();
		String[][] table;
		ArrayList<String[]> lines = new ArrayList<String[]>();
		TextureList textureList = new TextureList();
		
		logger.log(Level.INFO, "Reading TextureList.txt");
		
		while (result != null) {
			String[] pieces = result.split("\t");
			//System.out.println(result);
			//System.out.println(pieces.length);
			if (pieces.length!=0) {
				if (pieces[0].equalsIgnoreCase("End")) {
					String[] nameLine = lines.get(0);
					String name = nameLine[0];

					//				//compile full String[][] table
					//				for (int i = 0; i < lines.size(); i++) {
					//					String[] currLine = lines.get(i);
					//					for (int j = 0; j < currLine.length; j++) {
					//						table[i][j] = currLine[j];
					//						
					//					}
					//					
					//					
					//				}

					textureList.addTable(name, lines);
					lines = new ArrayList<String[]>();				
				}			
				else {
					lines.add(pieces);
				}
			}			
			result = br.readLine();
		}
		
		br.close();		
		data.setTextureList(textureList);
		//-----------------------------------------
		
		
		//-----------------------------------------
		//Custom Galaxies
		
		
		
		//-----------------------------------------
		
		
		
		
		
		//-----------------------------------------
		//AudioMapping.txt
		file = new File(Constants.dataPath + "//AudioMapping.txt");
		fr = new FileReader(file);		
		br = new BufferedReader(fr);
		
		result = br.readLine();
		result = br.readLine();
		
		AudioParameters audioParams = new AudioParameters();
		
		logger.log(Level.INFO, "Reading AudioMapping.txt");
		
		while (result!=null) {			
			String[] pieces = result.split("\t");
			
			AudioInformation audioData = new AudioInformation(pieces[0], Constants.audioPath + pieces[1]);
			audioData.setVolumeGain(Float.parseFloat(pieces[2]));
			audioData.setPitchLevel(Float.parseFloat(pieces[3]));
			audioData.setTimeOffset(Float.parseFloat(pieces[4]));
			audioData.setStreaming(Boolean.parseBoolean(pieces[5]));
			
			audioParams.addParameter(pieces[0], audioData);
			
			result = br.readLine();
		}
		br.close();
		
		data.setAudioParameters(audioParams);		
		//-----------------------------------------
		
		
		
		
		
		
		
		return data;
	}
	
	
	public ExternalData getData() {
		return this.data;
	}
	
	
	
	
	
//	private boolean isTXT(File file) {
//		int extensionPoint;
//		String fileExtension;
//		String fileName;
//		fileName = file.getName();
//		extensionPoint = fileName.lastIndexOf(".");
//		fileExtension = fileName.substring(extensionPoint+1, fileName.length());
//		
//		if (fileExtension.equalsIgnoreCase("txt")) {
//			return true;
//		}
//		else
//			return false;		
//	}
	

}
